package 多线程4;
//自己实现一个简单版本的线程池

import java.lang.management.RuntimeMXBean;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 1.描述一个任务.直接使用Runnable即可.
 * 2.组织若干个任务,可以使用一个阻塞队列(希望全局只有一个阻塞队列)
 * 3.有一些工作线程
 */
public class TestDemo5 {
    static class Worker extends Thread{
        private BlockingQueue<Runnable> queue = null;
        public Worker(BlockingQueue<Runnable> queue){
            this.queue = queue;
        }
        @Override
        public void run() {
            //工作线程的具体逻辑
            //需要从阻塞队列中取任务.
            while(true){
                try {
                    Runnable command = queue.take();
                    //通过run来执行具体的任务
                    command.run();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }
    }
    static class ThreadPool{
        //包含一个阻塞队列,用来组织任务
        private BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();

        //这个list就用来存放当前的工作线程.
        private List<Thread> workers = new ArrayList<>();
        //线程最大数量
        private static final int MAX_WORKER_COUNT = 10;

        //通过这个方法,把任务加入到线程池中.
        //submit不光可以把任务方法放到阻塞队列中,同时也可以负责创建线程.
        public void submit(Runnable command) throws InterruptedException {
            if (workers.size() < MAX_WORKER_COUNT){
                //如果当前工作线程的数量不足线程数目上限,就创建出新的线程.
                //工作线程就专门搞一个类来完成
                //worker内部要能取到队列的内容,就需要把这个队列的实例通过Worker的构造方法,传过去.
                Worker worker = new Worker(queue);
                worker.start();
                workers.add(worker);
            }
            queue.put(command);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadPool pool = new ThreadPool();
        for (int i = 0; i < 100; i++) {
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello");
                }
            });
        }
    }
}
